<!DOCTYPE html>
<html>
<head>
    <title>设备监控动态动画调整 - Babylon.js</title>
    <script src="https://cdn.babylonjs.com/babylon.js"></script>
    <script src="https://cdn.babylonjs.com/loaders/babylonjs.loaders.min.js"></script>
    <style>
        body {
            margin: 0;
            overflow: hidden;
            font-family: Arial, sans-serif;
        }
        #renderCanvas {
            width: 100%;
            height: 100%;
        }
        .control-panel {
            position: absolute;
            top: 10px;
            left: 10px;
            background: rgba(0, 0, 0, 0.7);
            color: white;
            padding: 15px;
            border-radius: 8px;
            width: 250px;
        }
        .control-group {
            margin-bottom: 15px;
        }
        label {
            display: block;
            margin-bottom: 5px;
            font-size: 14px;
        }
        input[type="range"] {
            width: 100%;
        }
        .value-display {
            text-align: right;
            font-size: 12px;
            color: #ccc;
        }
        button {
            width: 100%;
            padding: 8px;
            margin-top: 5px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
        }
        button:hover {
            background-color: #45a049;
        }
        #stopAnimation {
            background-color: #f44336;
        }
        #stopAnimation:hover {
            background-color: #d32f2f;
        }
    </style>
</head>
<body>
    <canvas id="renderCanvas"></canvas>
    <div class="control-panel">
        <h3>设备动画控制</h3>
        
        <div class="control-group">
            <label>旋转速度</label>
            <input type="range" id="rotationSpeed" min="0" max="2" step="0.1" value="0.5">
            <div class="value-display" id="rotationSpeedValue">0.5</div>
        </div>
        
        <div class="control-group">
            <label>颜色变化速度</label>
            <input type="range" id="colorSpeed" min="0" max="5" step="0.1" value="1">
            <div class="value-display" id="colorSpeedValue">1.0</div>
        </div>
        
        <div class="control-group">
            <label>缩放幅度</label>
            <input type="range" id="scaleAmount" min="0" max="0.5" step="0.05" value="0.2">
            <div class="value-display" id="scaleAmountValue">0.2</div>
        </div>
        
        <div class="control-group">
            <label>缩放速度</label>
            <input type="range" id="scaleSpeed" min="0" max="5" step="0.1" value="2">
            <div class="value-display" id="scaleSpeedValue">2.0</div>
        </div>
        
        <button id="resetAnimation">重置动画</button>
        <button id="stopAnimation">停止动画</button>
        <button id="startAnimation">启动动画</button>
    </div>

    <script>
        // 获取画布元素
        const canvas = document.getElementById("renderCanvas");
        
        // 创建引擎
        const engine = new BABYLON.Engine(canvas, true);
        
        // 动画控制变量
        let rotationSpeed = 0.5;
        let colorSpeed = 1;
        let scaleAmount = 0.2;
        let scaleSpeed = 2;
        let animationsActive = true; // 动画状态标志
        
        // 创建场景
        function createScene() {
            const scene = new BABYLON.Scene(engine);
            
            // 设置相机
            const camera = new BABYLON.ArcRotateCamera(
                "camera", 
                -Math.PI / 2, 
                Math.PI / 2.5, 
                10, 
                new BABYLON.Vector3(0, 0, 0), 
                scene
            );
            camera.attachControl(canvas, true);
            
            // 添加两个HemisphericLight提供自然光照
            const mainLight = new BABYLON.HemisphericLight(
                "mainLight", 
                new BABYLON.Vector3(0, 1, 0), 
                scene
            );
            mainLight.intensity = 0.7;
            mainLight.groundColor = new BABYLON.Color3(0.2, 0.2, 0.3);
            
            const sideLight = new BABYLON.HemisphericLight(
                "sideLight", 
                new BABYLON.Vector3(1, 0.5, 0), 
                scene
            );
            sideLight.intensity = 0.4;
            sideLight.groundColor = new BABYLON.Color3(0.1, 0.1, 0.1);
            
            // 创建设备模型
            const createDevice = () => {
                // 设备主体
                const deviceBody = BABYLON.MeshBuilder.CreateCylinder(
                    "deviceBody", 
                    { height: 2, diameter: 1.5, tessellation: 12 }, 
                    scene
                );
                deviceBody.position.y = 1;
                
                // 设备顶部
                const deviceTop = BABYLON.MeshBuilder.CreateCylinder(
                    "deviceTop", 
                    { height: 0.5, diameter: 1.2 }, 
                    scene
                );
                deviceTop.position.y = 2.25;
                
                // 设备底部
                const deviceBase = BABYLON.MeshBuilder.CreateCylinder(
                    "deviceBase", 
                    { height: 0.3, diameter: 2 }, 
                    scene
                );
                deviceBase.position.y = 0.15;
                
                // 指示灯
                const indicatorLight = BABYLON.MeshBuilder.CreateSphere(
                    "indicatorLight", 
                    { diameter: 0.3 }, 
                    scene
                );
                indicatorLight.position = new BABYLON.Vector3(0.8, 1.5, 0);
                
                // 创建材质
                const bodyMaterial = new BABYLON.StandardMaterial("bodyMaterial", scene);
                bodyMaterial.diffuseColor = new BABYLON.Color3(0.2, 0.2, 0.2);
                bodyMaterial.specularColor = new BABYLON.Color3(0.5, 0.5, 0.5);
                
                const topMaterial = new BABYLON.StandardMaterial("topMaterial", scene);
                topMaterial.diffuseColor = new BABYLON.Color3(0.3, 0.3, 0.3);
                
                const indicatorMaterial = new BABYLON.StandardMaterial("indicatorMaterial", scene);
                indicatorMaterial.emissiveColor = new BABYLON.Color3(0, 1, 0);
                
                // 应用材质
                deviceBody.material = bodyMaterial;
                deviceTop.material = topMaterial;
                deviceBase.material = bodyMaterial;
                indicatorLight.material = indicatorMaterial;
                
                // 将所有部分组合成一个父节点
                const device = new BABYLON.AbstractMesh("device", scene);
                deviceBody.parent = device;
                deviceTop.parent = device;
                deviceBase.parent = device;
                indicatorLight.parent = device;
                
                // 存储设备组件以便后续控制
                device.metadata = {
                    indicatorLight: indicatorLight,
                    indicatorMaterial: indicatorMaterial,
                    animations: [] // 存储动画引用
                };
                
                // 创建设备动画
                createDeviceAnimations(device);
                
                return device;
            };
            
            // 创建设备动画
            function createDeviceAnimations(device) {
                // 创建动画组
                const animationGroup = new BABYLON.AnimationGroup("deviceAnimations");
                
                // 1. 旋转动画
                const rotationAnimation = new BABYLON.Animation(
                    "rotationAnimation", 
                    "rotation.y", 
                    60, // 帧率
                    BABYLON.Animation.ANIMATIONTYPE_FLOAT,
                    BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE
                );
                
                const rotationKeys = [];
                rotationKeys.push({ frame: 0, value: 0 });
                rotationKeys.push({ frame: 60, value: Math.PI * 2 * rotationSpeed }); // 每秒旋转rotationSpeed圈
                rotationAnimation.setKeys(rotationKeys);
                
                // 2. 缩放动画
                const scalingAnimation = new BABYLON.Animation(
                    "scalingAnimation", 
                    "scaling.x", 
                    60, 
                    BABYLON.Animation.ANIMATIONTYPE_FLOAT,
                    BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE
                );
                
                const scalingKeys = [];
                scalingKeys.push({ frame: 0, value: 1 });
                scalingKeys.push({ frame: 30, value: 1 }); // 最大缩放
                scalingKeys.push({ frame: 60, value: 1 });
                scalingAnimation.setKeys(scalingKeys);
                
                // 3. 颜色动画
                const colorAnimation = new BABYLON.Animation(
                    "colorAnimation", 
                    "emissiveColor", 
                    60, 
                    BABYLON.Animation.ANIMATIONTYPE_COLOR3,
                    BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE
                );
                
                const colorKeys = [];
                colorKeys.push({ frame: 0, value: new BABYLON.Color3(0, 1, 0) }); // 绿色
                colorKeys.push({ frame: 30, value: new BABYLON.Color3(1, 1, 0) }); // 黄色
                colorKeys.push({ frame: 60, value: new BABYLON.Color3(1, 0, 0) }); // 红色
                colorAnimation.setKeys(colorKeys);
                
                // 将动画添加到动画组
                animationGroup.addTargetedAnimation(rotationAnimation, device);
                animationGroup.addTargetedAnimation(scalingAnimation, device);
                animationGroup.addTargetedAnimation(colorAnimation, device.metadata.indicatorMaterial);
                
                // 设置动画组属性
                animationGroup.loopAnimation = true;
                animationGroup.speedRatio = 1;
                
                // 启动动画组
                animationGroup.play(true);
                
                // 存储动画组引用
                device.metadata.animationGroup = animationGroup;
                device.metadata.animations = [rotationAnimation, scalingAnimation, colorAnimation];
            }
            
            // 创建设备
            const device = createDevice();
            
            // 创建一些辅助设备
            for (let i = 0; i < 3; i++) {
                const helperDevice = createDevice();
                helperDevice.scaling = new BABYLON.Vector3(0.5, 0.5, 0.5);
                const angle = (i * 2 * Math.PI) / 3;
                helperDevice.position.x = 3 * Math.cos(angle);
                helperDevice.position.z = 3 * Math.sin(angle);
            }
            
            // 添加地面
            const ground = BABYLON.MeshBuilder.CreateGround(
                "ground", 
                { width: 10, height: 10 }, 
                scene
            );
            const groundMaterial = new BABYLON.StandardMaterial("groundMaterial", scene);
            groundMaterial.diffuseColor = new BABYLON.Color3(0.1, 0.1, 0.1);
            ground.material = groundMaterial;
            
            return scene;
        }
        
        // 创建场景
        const scene = createScene();
        
        // 控制面板交互
        document.getElementById("rotationSpeed").addEventListener("input", function(e) {
            rotationSpeed = parseFloat(e.target.value);
            document.getElementById("rotationSpeedValue").textContent = rotationSpeed.toFixed(1);
            
            // 更新所有设备的旋转速度
            scene.meshes.forEach(mesh => {
                if (mesh.name === "device" && mesh.metadata && mesh.metadata.animationGroup) {
                    const animationGroup = mesh.metadata.animationGroup;
                    
                    // 遍历动画组中的所有动画
                    animationGroup.targetedAnimations.forEach(targetedAnim => {
                        if (targetedAnim.animation.name === "rotationAnimation") {
                            // 调整旋转动画的目标值
                            const keys = targetedAnim.animation.getKeys();
                            keys[1].value = Math.PI * 2 * rotationSpeed;
                            targetedAnim.animation.setKeys(keys);
                        }
                    });
                }
            });
        });
        
        document.getElementById("colorSpeed").addEventListener("input", function(e) {
            colorSpeed = parseFloat(e.target.value);
            document.getElementById("colorSpeedValue").textContent = colorSpeed.toFixed(1);
            
            // 更新所有指示灯的颜色变化速度
            scene.meshes.forEach(mesh => {
                if (mesh.name === "device" && mesh.metadata && mesh.metadata.animationGroup) {
                    const animationGroup = mesh.metadata.animationGroup;
                    
                    // 遍历动画组中的所有动画
                    animationGroup.targetedAnimations.forEach(targetedAnim => {
                        if (targetedAnim.animation.name === "colorAnimation") {
                            targetedAnim.animation.speedRatio = colorSpeed / 3;
                        }
                    });
                }
            });
        });
        
        document.getElementById("scaleAmount").addEventListener("input", function(e) {
            scaleAmount = parseFloat(e.target.value);
            document.getElementById("scaleAmountValue").textContent = scaleAmount.toFixed(2);
            
            // 更新所有设备的缩放幅度
            scene.meshes.forEach(mesh => {
                if (mesh.name === "device" && mesh.metadata && mesh.metadata.animationGroup) {
                    const animationGroup = mesh.metadata.animationGroup;
                    
                    // 遍历动画组中的所有动画
                    animationGroup.targetedAnimations.forEach(targetedAnim => {
                        if (targetedAnim.animation.name === "scalingAnimation") {
                            // 更新缩放动画的中间值
                            const keys = targetedAnim.animation.getKeys();
                            keys[1].value = 1 + scaleAmount;
                            targetedAnim.animation.setKeys(keys);
                        }
                    });
                }
            });
        });
        
        document.getElementById("scaleSpeed").addEventListener("input", function(e) {
            scaleSpeed = parseFloat(e.target.value);
            document.getElementById("scaleSpeedValue").textContent = scaleSpeed.toFixed(1);
            
            // 更新所有设备的缩放速度
            scene.meshes.forEach(mesh => {
                if (mesh.name === "device" && mesh.metadata && mesh.metadata.animationGroup) {
                    const animationGroup = mesh.metadata.animationGroup;
                    
                    // 遍历动画组中的所有动画
                    animationGroup.targetedAnimations.forEach(targetedAnim => {
                        if (targetedAnim.animation.name === "scalingAnimation") {
                            targetedAnim.animation.speedRatio = scaleSpeed / 2;
                        }
                    });
                }
            });
        });
        
        document.getElementById("resetAnimation").addEventListener("click", function() {
            // 重置控制值
            document.getElementById("rotationSpeed").value = 0.5;
            document.getElementById("colorSpeed").value = 1;
            document.getElementById("scaleAmount").value = 0.2;
            document.getElementById("scaleSpeed").value = 2;
            
            // 更新显示值
            document.getElementById("rotationSpeedValue").textContent = "0.5";
            document.getElementById("colorSpeedValue").textContent = "1.0";
            document.getElementById("scaleAmountValue").textContent = "0.2";
            document.getElementById("scaleSpeedValue").textContent = "2.0";
            
            // 更新动画变量
            rotationSpeed = 0.5;
            colorSpeed = 1;
            scaleAmount = 0.2;
            scaleSpeed = 2;
            
            // 重置所有设备的动画
            scene.meshes.forEach(mesh => {
                if (mesh.name === "device" && mesh.metadata && mesh.metadata.animationGroup) {
                    const animationGroup = mesh.metadata.animationGroup;
                    
                    // 重置旋转
                    mesh.rotation.y = 0;
                    
                    // 重置缩放
                    mesh.scaling = new BABYLON.Vector3(1, 1, 1);
                    
                    // 重置颜色
                    mesh.metadata.indicatorMaterial.emissiveColor = new BABYLON.Color3(0, 1, 0);
                    
                    // 遍历动画组中的所有动画，重置参数
                    animationGroup.targetedAnimations.forEach(targetedAnim => {
                        if (targetedAnim.animation.name === "rotationAnimation") {
                            const keys = targetedAnim.animation.getKeys();
                            keys[1].value = Math.PI * 2 * rotationSpeed;
                            targetedAnim.animation.setKeys(keys);
                        } else if (targetedAnim.animation.name === "scalingAnimation") {
                            const keys = targetedAnim.animation.getKeys();
                            keys[1].value = 1 + scaleAmount;
                            targetedAnim.animation.setKeys(keys);
                            targetedAnim.animation.speedRatio = scaleSpeed / 2;
                        } else if (targetedAnim.animation.name === "colorAnimation") {
                            targetedAnim.animation.speedRatio = colorSpeed / 3;
                        }
                    });
                    
                    // 重新启动动画组
                    animationGroup.restart();
                    animationsActive = true;
                }
            });
        });
        
        document.getElementById("stopAnimation").addEventListener("click", function() {
            // 停止所有设备的动画
            scene.meshes.forEach(mesh => {
                if (mesh.name === "device" && mesh.metadata && mesh.metadata.animationGroup) {
                    const animationGroup = mesh.metadata.animationGroup;
                    animationGroup.pause();
                    
                    // 存储当前动画状态以便恢复
                    mesh.metadata.lastAnimationFrame = animationGroup.currentFrame;
                }
            });
            
            animationsActive = false;
        });
        
        document.getElementById("startAnimation").addEventListener("click", function() {
            // 启动所有设备的动画
            scene.meshes.forEach(mesh => {
                if (mesh.name === "device" && mesh.metadata && mesh.metadata.animationGroup) {
                    const animationGroup = mesh.metadata.animationGroup;
                    
                    // 从上次暂停的位置恢复
                    if (mesh.metadata.lastAnimationFrame !== undefined) {
                        animationGroup.goToFrame(mesh.metadata.lastAnimationFrame);
                    }
                    
                    animationGroup.play();
                }
            });
            
            animationsActive = true;
        });
        
        // 渲染循环
        engine.runRenderLoop(() => {
            scene.render();
        });
        
        // 窗口大小变化时调整渲染
        window.addEventListener("resize", () => {
            engine.resize();
        });
    </script>
</body>
</html>